package com.king.netty.dubbo.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.Callable;

/**
 * @Author king
 * @Date 2021-04-13 16:13
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    /**
     * 上下文
     */
    private ChannelHandlerContext context;
    /**
     * 返回的结果
     */
    private String result;
    /**
     * 客户端调用方法时传入的参数
     */
    private String param;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelActive 被调用");
        // 提供给其它方法使用
        context = ctx;
    }

    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("channelRead 被调用");
        result = msg.toString();
        /*
            唤醒等待的线程
                客户端通过 call 发送给服务端之后当前线程进入 wait 状态，等待服务端返回结果
                服务端返回结果，通过 channelRead 方法接收，需要唤醒进入等待状态的线程执行后续操作
         */
        notify();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    /**
     * 被代理对象调用，发送数据给服务器，等待被唤醒执行后续操作
     *
     * @author king
     * @date 2021-04-13 16:29
     * @return java.lang.Object
     */
    @Override
    public synchronized Object call() throws Exception {
        System.out.println("call1 被调用");
        // 发送消息
        context.writeAndFlush(param);

        // 等待返回结果
        wait();
        System.out.println("call2 被调用");
        // 输出结果
        return result;
    }

    void setParam(String param) {
        System.out.println("setParam 被调用");
        this.param = param;
    }
}
